import os
import pandas as pd
import numpy as np
import openpyxl
from openpyxl.styles import Alignment, Font, PatternFill, Border, Side
from openpyxl.utils import get_column_letter


def compare_header_data_consistency(
    input_dir="input",
    output_dir="output",
    file1_name="表1.xlsx",
    file2_name="表2.xlsx",
    match_header="ID",  # 用于匹配行的表头
    compare_header="金额",  # 需要对比一致性的表头
    output_file="数据不一致结果.xlsx",
):
    """
    对比两个表中相同ID的行，检查指定表头数据是否一致

    参数:
    - input_dir: 输入目录
    - output_dir: 输出目录
    - file1_name: 第一个表文件名
    - file2_name: 第二个表文件名
    - match_header: 用于匹配行的表头（如ID）
    - compare_header: 需要对比一致性的表头
    - output_file: 输出文件名

    返回:
    - 输出文件路径
    """
    # 文件路径
    file1_path = os.path.join(input_dir, file1_name)
    file2_path = os.path.join(input_dir, file2_name)

    # 检查文件是否存在
    if not os.path.exists(file1_path):
        raise FileNotFoundError(f"文件不存在: {file1_path}")
    if not os.path.exists(file2_path):
        raise FileNotFoundError(f"文件不存在: {file2_path}")

    # 读取 Excel 文件
    try:
        df1 = pd.read_excel(file1_path, dtype=str)
        df2 = pd.read_excel(file2_path, dtype=str)
    except Exception as e:
        raise ValueError(f"读取 Excel 失败: {e}")

    # 检查必需表头是否存在
    if match_header not in df1.columns:
        raise ValueError(f"匹配表头 '{match_header}' 在第一个表中不存在")
    if match_header not in df2.columns:
        raise ValueError(f"匹配表头 '{match_header}' 在第二个表中不存在")
    if compare_header not in df1.columns:
        raise ValueError(f"对比表头 '{compare_header}' 在第一个表中不存在")
    if compare_header not in df2.columns:
        raise ValueError(f"对比表头 '{compare_header}' 在第二个表中不存在")

    # 获取两个表中都存在的匹配值
    df1_match_values = set(df1[match_header].dropna().astype(str))
    df2_match_values = set(df2[match_header].dropna().astype(str))
    common_match_values = df1_match_values.intersection(df2_match_values)

    print(f"两个表中共有 {len(common_match_values)} 个相同的 {match_header}")

    # 存储不一致的记录
    inconsistent_records = []

    for match_value in common_match_values:
        # 获取两个表中对应匹配值的行
        df1_row = df1[df1[match_header].astype(str) == match_value]
        df2_row = df2[df2[match_header].astype(str) == match_value]

        if len(df1_row) > 0 and len(df2_row) > 0:
            # 获取对比字段的值
            df1_compare_value = (
                df1_row[compare_header].iloc[0] if len(df1_row) > 0 else None
            )
            df2_compare_value = (
                df2_row[compare_header].iloc[0] if len(df2_row) > 0 else None
            )

            # 比较值是否一致
            if df1_compare_value != df2_compare_value:
                # 创建不一致记录
                record = {
                    match_header: match_value,
                    f"{compare_header}_表1": df1_compare_value,
                    f"{compare_header}_表2": df2_compare_value,
                    "异常备注": f"{compare_header}不一致: 表1={df1_compare_value}, 表2={df2_compare_value}",
                }

                # 添加两个表的其他字段（可选）
                # 这里可以添加更多字段以提供更多上下文信息
                inconsistent_records.append(record)

    # 创建结果DataFrame
    if inconsistent_records:
        result_df = pd.DataFrame(inconsistent_records)

        # 重新设置序号
        result_df = result_df.reset_index(drop=True)
        result_df.insert(0, "序号", range(1, len(result_df) + 1))
    else:
        # 如果没有不一致的记录，创建一个空的DataFrame
        result_df = pd.DataFrame(
            {
                "序号": [],
                match_header: [],
                f"{compare_header}_表1": [],
                f"{compare_header}_表2": [],
                "异常备注": [],
            }
        )
        print("没有找到数据不一致的记录")

    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)
    output_path = os.path.join(output_dir, output_file)

    # 保存结果并美化表格
    try:
        # 先保存数据
        result_df.to_excel(output_path, index=False, sheet_name="数据不一致")

        # 然后打开文件设置样式
        workbook = openpyxl.load_workbook(output_path)
        worksheet = workbook["数据不一致"]

        # 设置行高
        for row in range(2, len(result_df) + 2):  # 从第2行开始（跳过表头）
            worksheet.row_dimensions[row].height = 25

        # 设置表头行高和样式
        header_row = 1
        worksheet.row_dimensions[header_row].height = 30

        # 设置列宽自适应
        for idx, col in enumerate(result_df.columns, 1):
            column_letter = get_column_letter(idx)

            # 计算列宽（基于内容长度）
            max_length = 0
            column_data = result_df[col].astype(str)

            # 计算表头宽度
            header_length = len(str(col))
            max_length = max(max_length, header_length)

            # 计算内容最大宽度
            content_length = column_data.str.len().max()
            max_length = max(max_length, content_length)

            # 设置列宽（添加一些边距）
            adjusted_width = min(max_length + 4, 50)  # 最大宽度限制为50
            worksheet.column_dimensions[column_letter].width = adjusted_width

        # 创建样式对象
        center_alignment = Alignment(
            horizontal="center", vertical="center", wrap_text=True
        )
        bold_font = Font(bold=True, size=12)
        header_fill = PatternFill(
            start_color="D3D3D3", end_color="D3D3D3", fill_type="solid"
        )
        thin_border = Border(
            left=Side(style="thin"),
            right=Side(style="thin"),
            top=Side(style="thin"),
            bottom=Side(style="thin"),
        )

        # 创建异常行的样式（黄色背景）
        warning_fill = PatternFill(
            start_color="FFFF99", end_color="FFFF99", fill_type="solid"
        )

        # 设置所有单元格居中对齐和边框
        for row_idx, row in enumerate(
            worksheet.iter_rows(
                min_row=1,
                max_row=len(result_df) + 1,
                min_col=1,
                max_col=len(result_df.columns),
            ),
            1,
        ):
            for cell in row:
                cell.alignment = center_alignment
                cell.border = thin_border
                # 为数据行（非表头）设置黄色背景
                if row_idx > 1:
                    cell.fill = warning_fill

        # 设置表头样式
        for cell in worksheet[1]:
            cell.font = bold_font
            cell.fill = header_fill

        # 保存修改后的文件
        workbook.save(output_path)

    except Exception as e:
        raise ValueError(f"保存结果文件失败: {e}")

    print(f"对比完成: 共找到 {len(result_df)} 条数据不一致的记录")
    print(f"输出文件: {output_path}")

    return output_path
